import re
from typing import Optional
from .base_downloader import BaseDownloader

class DownloaderFactory:
    """下载器工厂，根据URL选择合适的下载器"""
    
    _instance = None
    _downloaders = {}
    
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super(DownloaderFactory, cls).__new__(cls)
            cls._instance._init_downloaders()
        return cls._instance
    
    def _init_downloaders(self):
        """初始化所有下载器"""
        # 导入所有下载器
        from .youtube_downloader import YouTubeDownloader
        from .douyin_downloader import DouyinDownloader
        from .kuaishou_downloader import KuaishouDownloader
        from .xiaohongshu_downloader import XiaohongshuDownloader
        from .xigua_downloader import XiguaDownloader
        from .bilibili_downloader import BilibiliDownloader
        from .toutiao_downloader import ToutiaoDownloader
        
        # 注册所有下载器
        self.register_downloader(r'(youtube\.com|youtu\.be)', YouTubeDownloader())
        self.register_downloader(r'(douyin\.com|iesdouyin\.com)', DouyinDownloader())
        self.register_downloader(r'kuaishou\.com', KuaishouDownloader())
        self.register_downloader(r'xiaohongshu\.com', XiaohongshuDownloader())
        self.register_downloader(r'ixigua\.com', XiguaDownloader())
        self.register_downloader(r'bilibili\.com', BilibiliDownloader())
        self.register_downloader(r'(toutiao\.com|toutiaoimg\.com)', ToutiaoDownloader())
    
    def register_downloader(self, pattern: str, downloader: BaseDownloader):
        """注册下载器
        
        Args:
            pattern: 正则表达式模式，用于匹配URL
            downloader: 下载器实例
        """
        self._downloaders[pattern] = downloader
    
    def get_downloader(self, url: str) -> Optional[BaseDownloader]:
        """根据URL获取合适的下载器
        
        Args:
            url: 视频URL
            
        Returns:
            匹配的下载器，如果没有匹配则返回None
        """
        for pattern, downloader in self._downloaders.items():
            if re.search(pattern, url):
                return downloader
        return None 